package com.cubesugar2014.secretcard;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import com.cubesugar2014.secretcard.SContent;
import com.cubesugar2014.secretcard.R;

import android.app.ActivityManager;
import android.app.ActivityManager.RecentTaskInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Notification.BigPictureStyle;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.IBinder;
import android.os.SystemClock;
import android.provider.Browser;
import android.support.v4.app.NotificationCompat;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.CheckBox;
import android.widget.Toast;


public class SService extends Service {
	static public void FLOG(String text)
	{       
	/*   File logFile = new File("sdcard/log_sc.txt");
	   if (!logFile.exists())
	   {
	      try
	      {
	         logFile.createNewFile();
	      } 
	      catch (IOException e)
	      {
	         // TODO Auto-generated catch block
	         e.printStackTrace();
	      }
	   }
	   try
	   {
	      //BufferedWriter for performance, true to set append to file flag
	      BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
	      buf.append(text);
	      buf.newLine();
	      buf.flush();
	      buf.close();
	   }
	   catch (IOException e)
	   {
	      // TODO Auto-generated catch block
	      e.printStackTrace();
	   }
	*/
	}
	

	public static final String PREFS_NAME = "ScardPrefsFile";

    private NotificationManager  mManager; 
	private Notification.Builder mBuilder;
	
	private Notification.BigPictureStyle mBigStyle;
	
	static public boolean mOnWorking = false;
	static public boolean mPause = false;

	
    private int mActNum = 0;
    private int mActImportance = 0;
    private int mPrevActNum = 0;
    
    private Bitmap mBitmap = null;
	private SharedPreferences mSettings;
	
	
	public static class SSAppInfo {
        public String name;
        public int count;

        public SSAppInfo(String name, int count ) 
        {
            this.name = name;
            this.count = count;
        }
        
        @Override
        public String toString() {
            return name;
        }
	}
     
	public class SSContainer
	{
	    List<SSAppInfo> mList = new ArrayList<SSAppInfo>();
	    public boolean contains(String name) {
            
	    	for (int i = 0; i < mList.size();i++)
	    	{
	    		if (mList.get(i).name.equals(name))
	    		{
	    			mList.get(i).count ++;
	    			return true;
	    		}
	    	}
	    	
	    	return false;
        }
	    public long count(String name) {
	    	for (int i = 0; i < mList.size();i++)
	    	{
	    		if (mList.get(i).name.equals(name))
	    		{
	    			return mList.get(i).count;
	    		}
	    	}
	    	
	    	return 0;
	    	
	    }
	    public boolean add(SSAppInfo obj)
	    {
	    	return mList.add(obj);
	    }
	    
	    public void clear()
	    {
	    	mList.clear();
	    }
	};
        /*
        @Override public boolean equals(Object aThat) {
          //check for self-comparison
          if ( this == aThat ) return true;
          
          //use instanceof instead of getClass here for two reasons
          //1. if need be, it can match any supertype, and not just one class;
          //2. it renders an explict check for "that == null" redundant, since
          //it does the check for null already - "null instanceof [type]" always
          //returns false. (See Effective Java by Joshua Bloch.)
          if ( !(aThat instanceof SSAppInfo) ) return false;
          //Alternative to the above line :
          //if ( aThat == null || aThat.getClass() != this.getClass() ) return false;

          //cast to native object is now safe
          SSAppInfo that = (SSAppInfo)aThat;
          
          return this.name == that.name;
        }
        */
    

    //private List<SSAppInfo> mPrevApp = new SSList<SSAppInfo>();
	private SSContainer mPrevApp = new SSContainer();
	private long mActivateTick = 0;
    private ActivityManager mActivityManager;

    private String mId;
    private static Timer timer = new Timer(); 
    

 	Boolean mAuto;
 	
    // Unique Identification Number for the Notification.
    // We use it on Notification start, and to cancel it.
    private int NOTIFICATION = 1234;
    private int NOTIFICATION2 = 5678;
    /**
     * Class for clients to access.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with
     * IPC.
     */
    public class LocalBinder extends Binder {
    	SService getService() {
            return SService.this;
        }
    }

    @Override
    public void onCreate() {
    	mManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    	mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      	mBuilder = new Notification.Builder(this);
    
       	
        // Display a notification about us starting.  We put an icon in the status bar.
        showNotification();
        
    	mSettings = getSharedPreferences(PREFS_NAME, 0);
    	
    	mActivityManager = (ActivityManager) this.getSystemService( ACTIVITY_SERVICE );
        
        TelephonyManager mgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
    	mId = mgr.getDeviceId();
    	
    	mBigStyle = new BigPictureStyle(mBuilder);
    	mBigStyle.setBigContentTitle("Your secret card");
    	mBigStyle.setSummaryText("Activated your image");
   		
        mAuto = mSettings.getBoolean("autoActivation", true);
        
        ItemListActivity.ItemInit(this);
        mOnWorking = true;
        
        timer.scheduleAtFixedRate(new mainTask(), 0, 2000);
        

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("LocalService", "Received start id " + startId + ": " + intent);
        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
    	
    	timer.cancel();
        // Cancel the persistent notification.
    	mManager.cancel(NOTIFICATION);

        // Tell the user we stopped.
        Toast.makeText(this, "sservice_stopped", Toast.LENGTH_SHORT).show();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    // This is the object that receives interactions from clients.  See
    // RemoteService for a more complete example.
    private final IBinder mBinder = new LocalBinder();

    /**
     * Show a notification while this service is running.
     */
    private void showNotification() {
      	mBuilder.setSmallIcon(R.drawable.ic_launcher);
       	mBuilder.setTicker("sWallet service on");
       	mBuilder.setWhen(System.currentTimeMillis());
       	mBuilder.setContentText("sWallet in cubesugar 2014 project");
       	mBuilder.setDefaults(Notification.DEFAULT_LIGHTS);
       			//Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
       	mBuilder.setAutoCancel(true);
       	PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, ItemListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
       	mBuilder.setContentIntent(pendingIntent);
      		 
       	mBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
       	
        // Send the notification.
    	//mManager.notify(NOTIFICATION, mBuilder.build());

   		//mManager.notify(NOTIFICATION2, mBuilder.build());
   		
    }
    
    private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }
    
    private Bitmap _LoadPicture(String seedKey) 
  	{
    	FLOG("ss loadpic");
    	
    	SContent.lock.lock();
    	
  		byte[] encryptedData = null;
          
          try {
  			
  			FileInputStream fIn = openFileInput(seedKey + ".bin");
  			long size = fIn.getChannel().size();
  			 
  			if (size <= 0 )
  			{
  				SContent.lock.unlock();
  			    return null;
  			}
  			
  			encryptedData = new byte[(int) size] ;
  			
  			
  			fIn.read(encryptedData);
  			fIn.close();
  			
  		} catch (FileNotFoundException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  			SContent.lock.unlock();
  		    return null;
  		} catch (IOException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  			SContent.lock.unlock();
  		    return null;
  		}
          
  		byte[] key = seedKey.getBytes();    
  		MessageDigest sha = null;
  		try {
  			sha = MessageDigest.getInstance("SHA-1");
  		} catch (NoSuchAlgorithmException e1) {
  			// TODO Auto-generated catch block
  			e1.printStackTrace();
  		}
  		key = sha.digest(key);
  		key = Arrays.copyOf(key, 16); // use only first 128 bit
  		
  		byte[] decryptedData = null;
  		
  		// decrypt
  		try {
  			decryptedData = decrypt(key, encryptedData);
  		} catch (Exception e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}
  		
  		SContent.lock.unlock();
  		return BitmapFactory.decodeByteArray(decryptedData, 0, decryptedData.length);
      }
    private String _LoadPackageName(String seedKey) 
    {
    	String line = null;
    		
    	try {
	  		  FileInputStream instream = openFileInput(seedKey + ".pn");
				  		  
	  		  if (instream != null) 
	  		  {
	  			  InputStreamReader inputreader = new InputStreamReader(instream);
	  			  BufferedReader buffreader = new BufferedReader(inputreader);
	  			
	  			  line = buffreader.readLine();
	  			
	  		  }
	  		  
	  		    			
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	 
    	return line;
    }
    
    private boolean _Activate(String appString)
    {

    SContent.lock.lock();
    
    	for (int i = 0; i < SContent.Count() ; i++)
   		{
    		 
    		String key = mId + SContent.ITEMS.get(i);
    	    String pName =_LoadPackageName(key);
           	
           	if (pName == null || !appString.equals(pName) || pName =="empty")
           		continue;
           	
          mBitmap = _LoadPicture(key);
              
          if (mBitmap == null)
          {
        	  SContent.lock.unlock();
              return false;
          }
          Bitmap bigPicture = mBitmap;
          
          mBigStyle.bigPicture(bigPicture);
     	  mBuilder.setStyle(mBigStyle);	
          //mBuilder.setContentText("test sWallet in cubesugar 2014 project");
     		
     	  mManager.notify(NOTIFICATION + i, mBuilder.build());
     		
     	  SContent.lock.unlock();
     	  return true;
   		}
    	
    	SContent.lock.unlock();
    	return false;
    }
    private boolean _RunWithApp(String appString)
    {
//    	mBigStyle.setSummaryText("testcount" + SContent.Count());
 //  		mManager.notify(NOTIFICATION2, mBuilder.build());
   		
    	SContent.lock.lock();
    	
    	for (int i = 0; i < SContent.Count() ; i++)
   		{
    		 
    		String key = mId + SContent.ITEMS.get(i);
    	    String pName =_LoadPackageName(key);
           	
           	if (pName == null || !appString.equals(pName) || pName =="empty")
           		continue;
//           	mBigStyle.setSummaryText("testkey" + key);
 //      		mManager.notify(NOTIFICATION2, mBuilder.build());
       		
           	

		    mPrevApp.add(new SSAppInfo(appString, 0));
		    /*
		    String key = mId + SContent.ITEMS.get(i);
	        
            mBitmap = _LoadPicture(key);
                
            if (mBitmap == null)
                return false;
            
            Bitmap bigPicture = mBitmap;
            
            mBigStyle.bigPicture(bigPicture);
       		mBuilder.setStyle(mBigStyle);	
           	//mBuilder.setContentText("test sWallet in cubesugar 2014 project");
       		
       		mManager.notify(NOTIFICATION + i, mBuilder.build());
       		*/
		    
		    mActivateTick = SystemClock.elapsedRealtime();
		    //SystemClock.currentThreadTimeMillis();
		    
		    SContent.lock.unlock();
		    return true;
	           
   		}
           
    	SContent.lock.unlock();
    	return false;
    	//mBuilder.setContentText("test sWallet in cubesugar 2014 project");
    	 // Send the notification.
    	//mManager.notify(NOTIFICATION, mBuilder.build());
    }
    
	private class mainTask extends TimerTask
    { 
        public void run() 
        {
          //  Toast.makeText(ctx, "test", Toast.LENGTH_SHORT).show();
        	//_LastURL();
        
        	mAuto = mSettings.getBoolean("autoActivation", true);

			
         	if (mAuto == true)
         	{
         		long t = SystemClock.elapsedRealtime();
         				//uptimeMillis();
         				//.currentThreadTimeMillis();
         		if ( t - mActivateTick > 9000)
        		{
//         			mBigStyle.setSummaryText("test" + mPrevApp.size());
 //              		mManager.notify(NOTIFICATION2, mBuilder.build());
               
               		
         			//mPrevApp = null;
         			//mPrevApp = new ArrayList<String>();
         			mPrevApp.clear();
        			mActivateTick = t;
        			
        			//mPause = false;
        		}
         		
         		if (mPause == true)
         			return;
         		
         		mActNum = 0;
         		
         		/*
         		old version
         	    List<RunningAppProcessInfo> procInfos = mActivityManager.getRunningAppProcesses();
         		         	    
         	    //if (procInfos.size() == mProcSize && mPrevApp != null)
        		//	return;
         			
         	    for (int j = 0; j < procInfos.size(); j++)
                {
                    String appString = procInfos.get(j).processName;
                 	
                    //if (appString.equals(mPrevApp) ) 
                    if (mPrevApp.contains(appString)) 
                    {
                    	if (mPrevApp.count(appString) == 3)
                    	{
                    		_Activate(appString);
                    	}
                    	
                    	continue;
                    }
                    
                    
                    if (_RunWithApp(appString) == true)
                    {
                    //	mProcSize = procInfos.size();
                    //	return;
                    	mActNum ++;
                  	     
                    }
                }
         	   */
         		
         		List<ActivityManager.RecentTaskInfo> info = mActivityManager.getRecentTasks(1, Intent.FLAG_ACTIVITY_NEW_TASK);

         		RecentTaskInfo recent = info.get(0);
         		Intent mIntent = recent.baseIntent;
         		String appString = mIntent. getComponent().getPackageName();
         	    
         		
                
         		if (mPrevApp.contains(appString)) 
                {
                	
         			if (mPrevApp.count(appString) == 3)
                	{
                		_Activate(appString);
                
                	}
                }
                    
                    
                if (_RunWithApp(appString) == true)
                {
                	mActNum ++;
              	     
                }
         		
         		
         	   mPrevActNum = mActNum;
         	    /*
         	   {
         	   int findValue = procInfos.get(0).importance;
         	   int index = 0;
               
         	   for (int j = 1; j < procInfos.size(); j++)
         	   {
                 int tt = procInfos.get(j).importance;
                 
                 if (findValue > tt) 
                 {
                	 findValue = tt;
                	 index = j;
                 }
         	   }
         	  
         	   String appString = procInfos.get(index).processName;
         	  
         	  if (mPrevApp == appString)
         		  return;
         	  
         	   if (_RunWithApp(appString) == true)
               {
         		   return;
               }
         	   
         	   }*/
         	}
        }
    }    
}


/*
public class SService extends Service{
	

	public static final String PREFS_NAME = "ScardPrefsFile";
	
    private String mPreURL = null;
    private long mActivateTick = 0;
    
    private NotificationManager mManager; 
	private Notification.Builder mBuilder;
    private int mProcSize = 0;
    
    private Bitmap mBitmap = null;

	static public boolean mOnWorking = false;
   
	public SharedPreferences mSettings;
	   
	
    private static Timer timer = new Timer(); 
    
   
    
    public String getDeviceId()
    {
	     TelephonyManager mgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
	     return mgr.getDeviceId();
	}

    private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }
    private String _LoadPackageName(String seedKey) 
    {
    	String line = null;
    		
    	try {
	  		  FileInputStream instream = openFileInput(seedKey + ".pn");
				  		  
	  		  if (instream != null) 
	  		  {
	  			  InputStreamReader inputreader = new InputStreamReader(instream);
	  			  BufferedReader buffreader = new BufferedReader(inputreader);
	  			
	  			  line = buffreader.readLine();
	  			
	  		  }
	  		  
	  		    			
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	 
    	return line;
    }
    private Bitmap _LoadPicture(String seedKey) 
  	{
  		byte[] encryptedData = null;
          
          try {
  			
  			FileInputStream fIn = openFileInput(seedKey + ".bin");
  			long size = fIn.getChannel().size();
  			 
  			if (size <= 0 )
  	            return null;
  			 
  			encryptedData = new byte[(int) size] ;
  			
  			
  			fIn.read(encryptedData);
  			fIn.close();
  			
  		} catch (FileNotFoundException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		    return null;
  		} catch (IOException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		    return null;
  		}
          
  		byte[] key = seedKey.getBytes();    
  		MessageDigest sha = null;
  		try {
  			sha = MessageDigest.getInstance("SHA-1");
  		} catch (NoSuchAlgorithmException e1) {
  			// TODO Auto-generated catch block
  			e1.printStackTrace();
  		}
  		key = sha.digest(key);
  		key = Arrays.copyOf(key, 16); // use only first 128 bit
  		
  		byte[] decryptedData = null;
  		
  		// decrypt
  		try {
  			decryptedData = decrypt(key, encryptedData);
  		} catch (Exception e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}
  		
  		return BitmapFactory.decodeByteArray(decryptedData, 0, decryptedData.length);
      }

	private boolean _CurrentApp()
	{
		
		

		if ( (SystemClock.currentThreadTimeMillis() - mActivateTick) > 3000)
		{
			mPreURL = null;
			mProcSize = 0;
			mActivateTick = SystemClock.currentThreadTimeMillis();
		}
	    	
		ActivityManager activityManager = (ActivityManager) this.getSystemService( ACTIVITY_SERVICE );
        List<RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
        
        if (procInfos.size() == mProcSize && mPreURL != null)
			return false;
		
        for(int j = 0; j < procInfos.size(); j++)
        {
            String appString = procInfos.get(j).processName;
         	
            if (appString.equals(mPreURL)) 
	    			return false;
            
            for (int i = 0; i < SContent.Count() ; i++)
    		{
            	String pName =_LoadPackageName(getDeviceId() + SContent.ITEMS.get(i));
            	
            	if (pName == null || !appString.equals(pName))
            		continue;
            	
            	Bitmap bigPicture;
    			
                mBitmap = _LoadPicture(getDeviceId() + SContent.ITEMS.get(i));
                 
                 if (mBitmap == null)
                 	return false;
                 
            	bigPicture = mBitmap;
    			    		
        		Notification.BigPictureStyle bigStyle = new BigPictureStyle(mBuilder);
        		bigStyle.setBigContentTitle("Your secret card");
        		bigStyle.setSummaryText("Activated your image");
        		bigStyle.bigPicture(bigPicture);
        		 
        		mBuilder.setStyle(bigStyle);
        		mManager.notify(111, mBuilder.build());
        		
        		{
 	           
 		    		
 		    		mPreURL = appString;
 		    		mActivateTick = SystemClock.currentThreadTimeMillis();
 		    		mProcSize = procInfos.size();
 		    		
	        		
        			return true;
 	            }
    		}
            
        }
        
        return false;
	}
	
	
	private class mainTask extends TimerTask
    { 
        public void run() 
        {
          //  Toast.makeText(ctx, "test", Toast.LENGTH_SHORT).show();
        	//_LastURL();
        
        	mSettings = getSharedPreferences(PREFS_NAME, 0);
         	Boolean auto = mSettings.getBoolean("autoActivation", false);
        
         	if (auto == true)
        		_CurrentApp();
        }
    }    
	
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
     
    @Override
    public void onStart(Intent intent, int startId) {
        Log.d("slog", "onStart()");
        super.onStart(intent, startId);
        
        
        mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      	PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, ItemListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
      				
      		 
      	mBuilder = new Notification.Builder(this);
      	mBuilder.setSmallIcon(R.drawable.ic_launcher);
      	mBuilder.setTicker("Activated your card");
      	mBuilder.setWhen(System.currentTimeMillis());
      	
      	mBuilder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
      	mBuilder.setContentIntent(pendingIntent);
      	mBuilder.setAutoCancel(true);
      		 
      	mBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
      			
        timer.scheduleAtFixedRate(new mainTask(), 1500, 1500);
        
        mOnWorking = true;
        
     	
    	
    }
     
    @Override
    public void onDestroy() { 
        Log.d("slog", "onDestroy()");
        super.onDestroy();
        
        mOnWorking = false;
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     
    	if ((intent != null) && (intent.getBooleanExtra("ALARM_RESTART_SERVICE_DIED", false)))
        {
            {
                return START_STICKY;
            }
        }
        // Do your other onStartCommand stuff..
        return START_STICKY;
    }
}*/